package ebedynky.services;

import ebedynky.beans.HibernateUtil;
import ebedynky.beans.Product;
import ebedynky.beans.ProductType;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

/**
 * @author Ondrej David (davidon1)
 */
public class ProductTypeService {

    /**
     * Seesion - current connection to the db.
     */
    private Session session;

    /**
     * Constructor, retrieces the session (connection).
     */
    public ProductTypeService() {
        this.session = HibernateUtil.getSessionFactory().openSession();
    }

    /**
     * Closes the session (connection).
     * @return success/failure.
     */
    public boolean close() {
        this.session.close();
        return !(this.session.isOpen());
    }

    /**
     * Restarts the session (connection).
     * @return success/failure.
     */
    public boolean restart() {
        this.session.close();
        if (this.session.isOpen()) {
            throw new IllegalStateException("Session could not be closed.");
        }
        this.session = HibernateUtil.getSessionFactory().openSession();
        return this.session.isOpen();
    }

    /**
     * Adds type to the db.
     * @param type ProductType to be inserted
     * @return ID of the added ProductType
     */
    public int addProductType(ProductType type) {
        session.beginTransaction();
        int id = getMaxProductTypeID() + 1;
        type.setProductTypeID(id);
        id = (Integer) session.save(type);
        session.getTransaction().commit();
        return (id);
    }

    /**
     * Retrieves the maximum id currently in the database of ProductTypes.
     * @return Max ID
     */
    public int getMaxProductTypeID() {
        String hql = "select max(p.productTypeID) from ProductType p";
        List list = session.createQuery(hql).list();
        if (list.get(0) != null) {
            Integer maxtypeid = (Integer) list.get(0);
            return maxtypeid;
        } else {
            return 0;
        }
    }

    /**
     * Retrieves a ProductType identified by the ID.
     * @param id of the ProductType
     * @return ProductType with the ID given (null if not found)
     */
    public ProductType getProductTypeByID(int id) {
        session.beginTransaction();
        ProductType type = (ProductType) session.get(ProductType.class, new Integer(id));
        session.getTransaction().commit();
        return (type);
    }

    /**
     * Retrieves a list of all ProductTypes stored in the db.
     * @return List of all ProductTypes (null if no ProductTypes)
     */
    public List<ProductType> getAllProductTypes() {
        session.beginTransaction();
        List<ProductType> typeList = session.createQuery("from ProductType").list();
        session.getTransaction().commit();
        return (typeList);
    }

    /**
     * Updates a specified ProductType identified by ID.
     * @param newType an updated ProductType
     */
    public void updateProductType(ProductType newType) {
        session.beginTransaction();
        ProductType type = (ProductType) session.get(Product.class, new Integer(newType.getProductTypeID()));
        type.setCertified(newType.isCertified());
        type.setHalal(newType.isHalal());
        type.setKosher(newType.isKosher());
        type.setOrganic(newType.isOrganic());
        type.setProducts(newType.getProducts());
        type.setVegan(newType.isVegan());
        type.setVegetarian(newType.isVegetarian());

        session.flush();
        session.getTransaction().commit();
        session.clear();
    }

    /**
     * Removes the ProductType from db.
     * @param id ProductType ID for removal
     * @return true if successful, false otherwise
     */
    public boolean deleteProductType(int id) {
        try {
            session.beginTransaction();
            ProductType type = (ProductType) session.get(ProductType.class, new Integer(id));
            session.delete(type);
            session.getTransaction().commit();
            return (true);
        } catch (HibernateException ex) {
            return (false);
        }
    }

    /**
     * Returns a list containing ProductTypes ordered by name.
     * @param name of the ProductType to be selected
     * @return List of ProductTypes, List containing ProductType with match, null if product not found
     */
    public List<ProductType> getProductTypeByName(String name) {
        session.beginTransaction();
        List<ProductType> type = null;
        if (name.equals("") || name == null) {
            type = session.createCriteria(ProductType.class).addOrder(Order.asc("type")).list();
        } else {
            type = session.createCriteria(ProductType.class).add(Restrictions.like("type", "%" + name + "%")).addOrder(Order.asc("type")).list();
        }
        session.getTransaction().commit();
        return (type);
    }
}
